package com.hfzy.ihk.web.websocket.aop;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hfzy.ihk.common.support.againtask.DelayQueueManager;
import com.hfzy.ihk.common.support.againtask.DelayWorker;
import com.hfzy.ihk.common.support.aop.AspectjHelper;
import com.hfzy.ihk.common.util.string.StringTools;
import com.hfzy.ihk.facade.websocket.linkcall.service.WebSocketService;
import com.hfzy.ihk.web.websocket.constant.Constants;
import com.hfzy.ihk.web.websocket.support.annotation.RePushDataToChrome;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 重推数据aop
 */
@Aspect
@Component
public class RePushDataToChromeHadler {

    private static  final Logger logger = LoggerFactory.getLogger(RePushDataToChromeHadler.class);

    @Autowired
    WebSocketService webSocketService;

    /**
     * 切入点
     */
    @Pointcut("@annotation(com.hfzy.ihk.web.websocket.support.annotation.RePushDataToChrome)")
    void pushChromeMessage() {
    }

    /**
     * 返回以后
     * @param joinPoint
     * @param returnInfo
     */
    @AfterReturning(value = "pushChromeMessage()",returning = "returnInfo")
    void pushChromeMessageAfterReturn(JoinPoint joinPoint,Object returnInfo) {

        logger.debug("param:" + JSON.toJSONString(joinPoint.getArgs()));
        logger.debug("returnRs is:" + JSON.toJSONString(returnInfo));

        try {
            RePushDataToChrome annotation = AspectjHelper.getMethodAnnotation( joinPoint,RePushDataToChrome.class);
            int timeOut = annotation.timeOut();
            int tryTimes = annotation.tryTimes();
            String type = annotation.type();
            doPush(tryTimes,timeOut,type,returnInfo,joinPoint.getArgs());
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    /**
     * 重推操作
     * @param tryTimes
     * @param timeOut
     * @param type
     * @param returnInfo
     * @param arg
     */
    public void doPush(int tryTimes,int timeOut,String type,Object returnInfo,Object[] arg){
        if((boolean)returnInfo)
            return;
        if(StringTools.isNotempty(arg)||arg.length<2||StringTools.isEmpty(arg[1]))
            return;

        DelayWorker delayWorker = new DelayWorker(tryTimes,timeOut,()->{
            //判断如果是 分析结果和 开始以及结束的消息就放入重推队列
            JSONObject json = JSON.parseObject(String.valueOf(arg[1]));

            if(!json.containsKey(Constants.WEB_SOCKET_JSON_KEY_MSG_TYPE)){
                return ;
            }

            if(Constants.WEB_SOCKET_MSG_TYPE_COMMIT_SUCCESS.equals(json.getString(Constants.WEB_SOCKET_JSON_KEY_MSG_TYPE)) //提交成功消息
                    ||Constants.WEB_SOCKET_MSG_TYPE_MAIN_FAILED.equals(json.getString(Constants.WEB_SOCKET_JSON_KEY_MSG_TYPE)) //主叫呼叫失败
                    ||Constants.WEB_SOCKET_MSG_TYPE_TARGET_FAILED.equals(json.getString(Constants.WEB_SOCKET_JSON_KEY_MSG_TYPE)) //呼被叫失败
                    ||Constants.WEB_SOCKET_MSG_TYPE_TARGET_DISCONNECTED.equals(json.getString(Constants.WEB_SOCKET_JSON_KEY_MSG_TYPE))//通话结束
                    ||Constants.WEB_SOCKET_MSG_TYPE_ANALYSE.equals(json.getString(Constants.WEB_SOCKET_JSON_KEY_MSG_TYPE))//分析结果
                    ){
                    Boolean bl= false;
                    if("token".equals(type)){
                        bl = webSocketService.pushToBrowserBySessionId(String.valueOf(arg[0]),String.valueOf(arg[1]));
                    }else if("sessionId".equals(type)){
                        bl = webSocketService.pushToBrowserByToken(String.valueOf(arg[0]),String.valueOf(arg[1]));
                    }
//                    if(!bl)  //在次调这个方法的时候会再切入，所以这里不需要抛异常了 执行一次就行了
//                        throw  new Exception(); //需要再次放入延迟队列需要抛异常出去
            }
        });
        DelayQueueManager.getInstance().put(delayWorker);//放入队列

    }



}
